use crate::{Environment, ProductType};
use serde::{Deserialize, Serialize};

/// Binance SDK配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct BinanceConfig {
    /// API密钥
    pub api_key: String,
    /// 密钥
    pub secret_key: String,
    /// 产品类型
    pub product_type: ProductType,
    /// 环境
    pub environment: Environment,
    /// HTTP代理 (可选)
    pub http_proxy: Option<String>,
    /// WebSocket代理 (可选)
    pub ws_proxy: Option<String>,
    /// 请求超时时间 (秒)
    pub timeout_seconds: u64,
    /// 重试次数
    pub retry_count: u32,
    /// 自定义端点 (可选)
    pub custom_endpoints: Option<CustomEndpoints>,
}

/// 自定义端点配置
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CustomEndpoints {
    pub rest_base_url: Option<String>,
    pub ws_base_url: Option<String>,
}

impl Default for BinanceConfig {
    fn default() -> Self {
        Self {
            api_key: String::new(),
            secret_key: String::new(),
            product_type: ProductType::Spot,
            environment: Environment::Demo,
            http_proxy: std::env::var("BINANCE_HTTP_PROXY").ok(),
            ws_proxy: std::env::var("BINANCE_WS_PROXY").ok(),
            timeout_seconds: 30,
            retry_count: 3,
            custom_endpoints: None,
        }
    }
}

impl BinanceConfig {
    /// 创建新的配置
    pub fn new(api_key: String, secret_key: String, product_type: ProductType) -> Self {
        Self {
            api_key,
            secret_key,
            product_type,
            environment: Environment::Demo,
            http_proxy: std::env::var("BINANCE_HTTP_PROXY").ok(),
            ws_proxy: std::env::var("BINANCE_WS_PROXY").ok(),
            timeout_seconds: 30,
            retry_count: 3,
            custom_endpoints: None,
        }
    }

    /// 设置环境
    pub fn with_environment(mut self, env: Environment) -> Self {
        self.environment = env;
        self
    }

    /// 设置代理
    pub fn with_proxy(mut self, http_proxy: Option<String>, ws_proxy: Option<String>) -> Self {
        self.http_proxy = http_proxy;
        self.ws_proxy = ws_proxy;
        self
    }

    /// 设置超时时间
    pub fn with_timeout(mut self, timeout_seconds: u64) -> Self {
        self.timeout_seconds = timeout_seconds;
        self
    }

    /// 设置重试次数
    pub fn with_retry_count(mut self, retry_count: u32) -> Self {
        self.retry_count = retry_count;
        self
    }

    /// 获取REST API基础URL
    pub fn rest_base_url(&self) -> String {
        if let Some(custom) = &self.custom_endpoints {
            if let Some(url) = &custom.rest_base_url {
                return url.clone();
            }
        }
        self.product_type.rest_base_url(self.environment).to_string()
    }

    /// 获取WebSocket基础URL
    pub fn ws_base_url(&self) -> String {
        if let Some(custom) = &self.custom_endpoints {
            if let Some(url) = &custom.ws_base_url {
                return url.clone();
            }
        }
        self.product_type.ws_base_url(self.environment).to_string()
    }


    /// 构建完整的REST URL
    pub fn rest_url(&self, endpoint: &str) -> String {
        let base = self.rest_base_url();
        let prefix = self.product_type.base_api_prefix();
        format!("{}{}{}", base, prefix, endpoint)
    }

    /// 构建完整的WebSocket URL
    pub fn ws_url(&self, stream: &str) -> String {
        let base = self.ws_base_url();
        format!("{}/{}", base, stream)
    }

    /// 从配置文件加载
    pub fn from_file(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
        let content = std::fs::read_to_string(path)?;
        let config: BinanceConfig = toml::from_str(&content)?;
        Ok(config)
    }

    /// 保存到配置文件
    pub fn save_to_file(&self, path: &str) -> Result<(), Box<dyn std::error::Error>> {
        let content = toml::to_string_pretty(self)?;
        std::fs::write(path, content)?;
        Ok(())
    }
}

/// 配置构建器
pub struct BinanceConfigBuilder {
    config: BinanceConfig,
}

impl BinanceConfigBuilder {
    pub fn new(api_key: String, secret_key: String, product_type: ProductType) -> Self {
        Self {
            config: BinanceConfig::new(api_key, secret_key, product_type),
        }
    }

    pub fn environment(mut self, env: Environment) -> Self {
        self.config.environment = env;
        self
    }

    pub fn proxy(mut self, http_proxy: Option<String>, ws_proxy: Option<String>) -> Self {
        self.config.http_proxy = http_proxy;
        self.config.ws_proxy = ws_proxy;
        self
    }

    pub fn timeout(mut self, timeout_seconds: u64) -> Self {
        self.config.timeout_seconds = timeout_seconds;
        self
    }

    pub fn retry_count(mut self, retry_count: u32) -> Self {
        self.config.retry_count = retry_count;
        self
    }

    pub fn custom_endpoints(mut self, endpoints: CustomEndpoints) -> Self {
        self.config.custom_endpoints = Some(endpoints);
        self
    }

    pub fn build(self) -> BinanceConfig {
        let mut config = self.config;
        
        // 如果配置中没有设置代理，尝试从环境变量加载
        if config.http_proxy.is_none() {
            config.http_proxy = std::env::var("BINANCE_HTTP_PROXY").ok();
        }
        if config.ws_proxy.is_none() {
            config.ws_proxy = std::env::var("BINANCE_WS_PROXY").ok();
        }
        
        config
    }
}
